package edu.hawaii.myisern.commandline;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import edu.hawaii.myisern.collaborations.jaxb.CollaboratingOrganizations;
import edu.hawaii.myisern.collaborations.jaxb.CollaborationTypes;
import edu.hawaii.myisern.collaborations.jaxb.OutcomeTypes;
import edu.hawaii.myisern.collaborations.jaxb.Years;
import edu.hawaii.myisern.organizations.jaxb.AffiliatedResearchers;
import edu.hawaii.myisern.organizations.jaxb.ResearchKeywords;

/**
 * Demonstrates that the MyIsernInput class is working.
 * 
 * @author Phuoc Le
 * @author Ka Yee Leung
 * @author Jared Sunouchi
 */
public class TestMyIsernInput {

  private String userDirectory = "user.dir";
  private File collaborationFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/input.test.collaborations.example.xml");
  private File organizationFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/input.test.organizations.example.xml");
  private File researcherFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/input.test.researchers.example.xml");

  private File validCollaborationFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/test.collaborations.example.xml");
  private File validOrganizationFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/test.organizations.example.xml");
  private File validResearcherFile = new File(System.getProperty(userDirectory)
      + "/xml/tests/test.researchers.example.xml");

  /**
   * Tests general methods of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testInput() throws Exception {
    try {
      MyIsernInput.checkLink("http://www.google.com");
    }
    catch (Exception error) {
      fail("Valid website was not valid");
    }
  }

  /**
   * Tests the modify methods of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testModifyMethods() throws Exception {
    String testValue3 = "test3, test4";
    String testValue3a = "test3";
    String testValue3b = "test4";
    List<String> testList = new ArrayList<String>();
    testList.add("test1");
    testList.add("test2");

    CollaboratingOrganizations testCollaboratingOrgs = new CollaboratingOrganizations();
    CollaborationTypes testCollaborationTypes = new CollaborationTypes();
    OutcomeTypes testOutcomeTypes = new OutcomeTypes();
    ResearchKeywords testResearchKeywords = new ResearchKeywords();
    AffiliatedResearchers testAffiliatedResearchers = new AffiliatedResearchers();
    Years testYears = new Years();

    for (String stringArg : testList) {
      testCollaboratingOrgs.getCollaboratingOrganization().add(stringArg);
      testCollaborationTypes.getCollaborationType().add(stringArg);
      testOutcomeTypes.getOutcomeType().add(stringArg);
      testResearchKeywords.getResearchKeyword().add(stringArg);
      testAffiliatedResearchers.getAffiliatedResearcher().add(stringArg);
    }

    for (int i = 0; i < 2; i++) {
      Integer testInt = i;
      BigInteger testBigInt = new BigInteger(testInt.toString());
      testYears.getYear().add(testBigInt);
    }

    testList.add(testValue3a);
    testList.add(testValue3b);
    List<String> collaboratingOrgsResult = new ArrayList<String>();
    List<String> collaborationTypesResult = new ArrayList<String>();
    List<String> outcomeTypesResult = new ArrayList<String>();
    List<String> researchKeywordsResult = new ArrayList<String>();
    List<String> affiliatedResearchersResult = new ArrayList<String>();
    for (String stringArg : testList) {
      collaboratingOrgsResult.add(stringArg);
      collaborationTypesResult.add(stringArg);
      outcomeTypesResult.add(stringArg);
      researchKeywordsResult.add(stringArg);
      affiliatedResearchersResult.add(stringArg);
    }
    testYears.getYear().add(new BigInteger("2"));
    Years yearsResult = testYears;
    yearsResult.getYear().remove(new BigInteger("2"));

    assertEquals("Check modifyCollaboratingOrganizations", collaboratingOrgsResult, MyIsernInput
        .modifyCollaboratingOrganizations(testValue3, testCollaboratingOrgs)
        .getCollaboratingOrganization());
    assertEquals("Check modifyCollaborationTypes", collaborationTypesResult, MyIsernInput
        .modifyCollaborationTypes(testValue3, testCollaborationTypes).getCollaborationType());
    assertEquals("Check modifyCollaborationTypes", outcomeTypesResult, MyIsernInput
        .modifyOutcomeTypes(testValue3, testOutcomeTypes).getOutcomeType());
    assertEquals("Check modifyResearchKeywords", researchKeywordsResult, MyIsernInput
        .modifyResearchKeywords(testValue3, testResearchKeywords).getResearchKeyword());
    assertEquals("Check modifyAffiliatedResearchers", affiliatedResearchersResult, MyIsernInput
        .modifyAffiliatedResearchers(testValue3, testAffiliatedResearchers)
        .getAffiliatedResearcher());
    assertEquals("Check modifyAffiliatedResearchers", yearsResult.getYear(), MyIsernInput
        .modifyYears("2", testYears).getYear());
  }

  /**
   * Tests edit feature of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testAddInput() throws Exception {
    MyIsernXmlLoader copier = new MyIsernXmlLoader(validCollaborationFile, validOrganizationFile,
        validResearcherFile);
    String copyCollaborationsXml = copier.getCollaborationsXml();
    String copyOrganizationsXml = copier.getOrganizationsXml();
    String copyResearchersXml = copier.getResearchersXml();

    collaborationFile.delete();
    organizationFile.delete();
    researcherFile.delete();
    collaborationFile.createNewFile();
    organizationFile.createNewFile();
    researcherFile.createNewFile();

    FileOutputStream fos = new FileOutputStream(collaborationFile);
    fos.write(copyCollaborationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(organizationFile);
    fos.write(copyOrganizationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(researcherFile);
    fos.write(copyResearchersXml.getBytes());
    fos.close();

    MyIsernXmlLoader loader = new MyIsernXmlLoader(collaborationFile, organizationFile,
        researcherFile);
    loader.sanityCheck();

    // testing the add feature
    int numberOfResearchers = loader.getNumResearchers();
    numberOfResearchers++;
    FileReader file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input1.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();
    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);
    assertEquals("Check that researcher has been added", numberOfResearchers, loader
        .getNumResearchers());

    int numberOfOrganizations = loader.getNumOrganizations();
    numberOfOrganizations++;
    file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input2.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();
    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);
    assertEquals("Check that organization has been added", numberOfOrganizations, loader
        .getNumOrganizations());

    int numberOfCollaborations = loader.getNumCollaborations();
    numberOfCollaborations++;
    file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input3.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();
    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);
    assertEquals("Check that collaboration has been added", numberOfCollaborations, loader
        .getNumCollaborations());
  }

  /**
   * Tests edit researcher feature of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testResearcherEditInput() throws Exception {
    MyIsernXmlLoader copier = new MyIsernXmlLoader(validCollaborationFile, validOrganizationFile,
        validResearcherFile);
    String copyCollaborationsXml = copier.getCollaborationsXml();
    String copyOrganizationsXml = copier.getOrganizationsXml();
    String copyResearchersXml = copier.getResearchersXml();

    collaborationFile.delete();
    organizationFile.delete();
    researcherFile.delete();
    collaborationFile.createNewFile();
    organizationFile.createNewFile();
    researcherFile.createNewFile();

    FileOutputStream fos = new FileOutputStream(collaborationFile);
    fos.write(copyCollaborationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(organizationFile);
    fos.write(copyOrganizationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(researcherFile);
    fos.write(copyResearchersXml.getBytes());
    fos.close();

    MyIsernXmlLoader loader = new MyIsernXmlLoader(collaborationFile, organizationFile,
        researcherFile);
    loader.sanityCheck();

    int numberOfResearchers = loader.getNumResearchers();
    FileReader file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input4.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();

    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);

    assertEquals("Check that researcher has been added", numberOfResearchers, loader
        .getNumResearchers());
  }

  /**
   * Tests edit organization feature of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testOrganizationEditInput() throws Exception {
    MyIsernXmlLoader copier = new MyIsernXmlLoader(validCollaborationFile, validOrganizationFile,
        validResearcherFile);
    String copyCollaborationsXml = copier.getCollaborationsXml();
    String copyOrganizationsXml = copier.getOrganizationsXml();
    String copyResearchersXml = copier.getResearchersXml();

    collaborationFile.delete();
    organizationFile.delete();
    researcherFile.delete();
    collaborationFile.createNewFile();
    organizationFile.createNewFile();
    researcherFile.createNewFile();

    FileOutputStream fos = new FileOutputStream(collaborationFile);
    fos.write(copyCollaborationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(organizationFile);
    fos.write(copyOrganizationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(researcherFile);
    fos.write(copyResearchersXml.getBytes());
    fos.close();

    MyIsernXmlLoader loader = new MyIsernXmlLoader(collaborationFile, organizationFile,
        researcherFile);
    loader.sanityCheck();

    int numberOfOrganizations = loader.getNumOrganizations();
    FileReader file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input5.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();

    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);

    assertEquals("Check that organization has been added", numberOfOrganizations, loader
        .getNumOrganizations());
  }

  /**
   * Tests edit collaboration feature of MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testCollaborationEditInput() throws Exception {
    MyIsernXmlLoader copier = new MyIsernXmlLoader(validCollaborationFile, validOrganizationFile,
        validResearcherFile);
    String copyCollaborationsXml = copier.getCollaborationsXml();
    String copyOrganizationsXml = copier.getOrganizationsXml();
    String copyResearchersXml = copier.getResearchersXml();

    collaborationFile.delete();
    organizationFile.delete();
    researcherFile.delete();
    collaborationFile.createNewFile();
    organizationFile.createNewFile();
    researcherFile.createNewFile();

    FileOutputStream fos = new FileOutputStream(collaborationFile);
    fos.write(copyCollaborationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(organizationFile);
    fos.write(copyOrganizationsXml.getBytes());
    fos.close();
    fos = new FileOutputStream(researcherFile);
    fos.write(copyResearchersXml.getBytes());
    fos.close();

    MyIsernXmlLoader loader = new MyIsernXmlLoader(collaborationFile, organizationFile,
        researcherFile);
    loader.sanityCheck();

    int numberOfCollaborations = loader.getNumCollaborations();
    FileReader file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input6.txt");
    MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    file.close();

    loader = new MyIsernXmlLoader(collaborationFile, organizationFile, researcherFile);

    assertEquals("Check that collaboration has been added", numberOfCollaborations, loader
        .getNumCollaborations());
  }
  
  /**
   * Tests invalid commands in MyIsernInput.
   * 
   * @throws Exception If problems occur.
   */
  @Test
  public void testInvalidInput() throws Exception {
    MyIsernXmlLoader loader = new MyIsernXmlLoader(collaborationFile, organizationFile, 
        researcherFile);
    FileReader file = new FileReader(System.getProperty(userDirectory) + "/testFiles/input7.txt");
    try {
      MyIsernInput.setBufferedReaderAndRunInput(file, loader);
    }
    catch (Exception error) {
      fail("Uncaught exception occured.");
    }
    file.close();
  }
}
